package com.lovelc.cn;

import com.alibaba.druid.pool.DruidDataSource;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.json.JsonMapper;
import com.lovelc.cn.procesor.MyBeanProcessor;
import com.lovelc.cn.procesor.MyDataSource;
import com.sun.jndi.ldap.pool.PooledConnectionFactory;
import lombok.extern.slf4j.Slf4j;
import org.I0Itec.zkclient.IZkDataListener;
import org.I0Itec.zkclient.ZkClient;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Bean;

import javax.sql.DataSource;
import java.sql.SQLException;
import java.util.Arrays;
import java.util.Map;
import java.util.concurrent.ScheduledThreadPoolExecutor;

/**
 * @ClassName DemoApplication
 * @Description TODO
 * @Author huangjh5
 * @Date 2021/1/4 15:36
 */
@Slf4j
@SpringBootApplication
public class DemoApplication {


    public static void main(String[] args) {
        ConfigurableApplicationContext run = SpringApplication.run(DemoApplication.class, args);

        System.out.println(Arrays.asList(run.getBeanDefinitionNames()));


        ZkClient bean = run.getBeanFactory().getBean(ZkClient.class);
        //进行监听zk变化
        bean.subscribeDataChanges("/datasource/mysql_one", new IZkDataListener() {
            @Override
            public void handleDataChange(String dataPath, Object data) throws Exception {

                try {
                    System.out.println(String.format("变更数据源,拉取到数据源信息 json:%s",data.toString()) );
                    //进行注销
                    DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) run.getBeanFactory();
                    MyDataSource bean =  beanFactory.getBean(MyDataSource.class);
                    JsonMapper jsonMapper = new JsonMapper();
                    Map<String, String> map = jsonMapper.readValue(data.toString(), Map.class);
                    bean.restart(map.get("driverName"),map.get("dbUrl"),map.get("userName"),map.get("password"));

//                    beanFactory.removeBeanDefinition("dataSource");


                    //进行重启
//                    JsonMapper jsonMapper = new JsonMapper();
//                    bean.restart();
//                    Map<String, String> map = jsonMapper.readValue(data.toString(), Map.class);
//                    bean.setUrl(map.get("dbUrl"));
//                    bean.setDriverClassName(map.get("driverName"));
//                    bean.setUsername(map.get("userName"));
//                    bean.setPassword(map.get("password"));

                } catch (Exception e) {
                    e.printStackTrace();
                }



            }

            @Override
            public void handleDataDeleted(String dataPath) throws Exception {

            }
        });


    }


    @Bean
    public ZkClient getZkClient() {
        return new ZkClient("linux121:2181,linux122:2181");
    }


    @Bean(name = "dataSource")
    public DataSource getDataSource() throws SQLException, JsonProcessingException {
        ZkClient zkClient = new ZkClient("linux121:2181,linux122:2181");
        DruidDataSource dataSource = new DruidDataSource();
        String json = zkClient.readData("/datasource/mysql_one").toString();
        System.out.println(String.format("拉取到数据源信息 json:%s",json) );
        JsonMapper jsonMapper = new JsonMapper();
        Map<String, String> map = jsonMapper.readValue(json, Map.class);
        dataSource.setUrl(map.get("dbUrl"));
        dataSource.setDriverClassName(map.get("driverName"));
        dataSource.setUsername(map.get("userName"));
        dataSource.setPassword(map.get("password"));
        dataSource.init();
        return new MyDataSource(map.get("driverName"),map.get("dbUrl"),map.get("userName"),map.get("password"));
    }


}
